package com.sinopec.basemodule.adapter

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.BaseAdapter
import android.widget.Spinner
import com.sinopec.basemodule.R
import kotlinx.android.synthetic.main.spinner_text_adapter.view.*

/**
 * lwj at 2023/5/24
 * spinner的适配器
 */
abstract class BaseSpinnerAdapter<T>(
    private val layoutId: Int,
) : BaseAdapter() {

    init {

    }

    var itemClick: ((data: T?, position: Int) -> Unit)? = null

    private var data: MutableList<T?> = ArrayList<T?>()
        set(value) {
            field = value
            this.notifyDataSetChanged()
        }

    fun setNewInstance(data: MutableList<T?>) {
        this.data = data
        this.notifyDataSetChanged()
    }

    fun addData(one: T) {
        this.data.add(one)
        this.notifyDataSetChanged()
    }

    fun addData(datas: List<T>) {
        this.data.addAll(datas)
        notifyDataSetChanged()
    }

    fun addData(position: Int, datas: List<T>) {
        this.data.addAll(position, datas)
        notifyDataSetChanged()
    }

    fun addData(position: Int, data: T) {
        this.data.add(position, data)
        notifyDataSetChanged()
    }

    override fun getCount(): Int {
        return data.size
    }

    override fun getItem(position: Int): T? {
        return data[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        return (if (convertView != null) {
            convertView.also {
                onBindView(position, it, getItem(position))
            }
        } else {
            LayoutInflater.from(parent?.context).inflate(layoutId, parent, false).also {
                onViewCreated(position, it, parent)
                onBindView(position, it, getItem(position))
            }
        }).also {
            click(it, position)
        }
    }

    open fun click(view: View, position: Int) {
        view.setOnClickListener {
            itemClick?.invoke(getItem(position), position)
        }
    }

    open fun onViewCreated(position: Int, convertView: View, parent: ViewGroup?) {}

    abstract fun onBindView(position: Int, convertView: View, data: T?)

}

/**
 * lwj at 2023/5/29
 * 简易文本的
 * @param layoutId 里面必须有id为tvName的TextView
 */
class TextSpinnerAdapter<T>(
    layoutId: Int = R.layout.spinner_text_adapter,
    val getLabel: T.() -> String
) :
    BaseSpinnerAdapter<T>(layoutId) {
    override fun onBindView(position: Int, convertView: View, data: T?) {
        convertView.tvName.text = data?.getLabel()
    }
}

/**
 * lwj at 2023/5/24
 * 绑定 spinner
 * 用于 界面和列表显示不同的操作
 *
 * @param spinner spinner view控件
 * @param delegateView 显示在页面上的view
 * @param onSelect 选中事件
 *
 */
fun <T, Adapter : BaseSpinnerAdapter<T>> Adapter.bindSpinner(
    spinner: Spinner,
    delegateView: View,
    onSelect: (T?, isFirst: Boolean) -> Unit
): Adapter {
    var isFirst = true
    spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(
            parent: AdapterView<*>?,
            view: View?,
            position: Int,
            id: Long
        ) {
            onSelect(getItem(position), isFirst)
            isFirst = false
        }

        override fun onNothingSelected(parent: AdapterView<*>?) {
            onSelect(null, isFirst)
            isFirst = false
        }
    }

    val dismiss: (() -> Unit)? = try {
        val field = spinner.javaClass.getDeclaredField("mPopup")
        field.isAccessible = true
        val spinnerPop = field.get(spinner)
        val dismiss = spinnerPop.javaClass.superclass.getDeclaredMethod("dismiss")
        dismiss.isAccessible = true
        {
            try {
                dismiss.invoke(spinnerPop)
            } catch (e: Exception) {
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }

    itemClick = { data, position ->
        onSelect(data, isFirst)
        isFirst = false
        dismiss?.invoke()
    }
    delegateView.setOnTouchListener { v, event ->
        spinner.onTouchEvent(event)
    }
    return this
}